package com.tdcy.sys.service.impl;

import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.tdcy.framework.bean.PageInfo;
import com.tdcy.framework.exception.QuickuException;
import com.tdcy.sys.dao.IWxPayDAO;
import com.tdcy.sys.dao.IWxRefundDAO;
import com.tdcy.sys.dao.eo.WxPayEO;
import com.tdcy.sys.dao.eo.WxRefundEO;
import com.tdcy.sys.service.ISeqNoSvc;
import com.tdcy.sys.service.IWxPaySvc;
import com.tdcy.sys.service.bean.WxPayCondition;
import com.tdcy.sys.service.wxinf.OrderQueryInf;
import com.tdcy.sys.service.wxinf.RefundInf;
import com.tdcy.sys.service.wxinf.UnifiedorderInf;
import com.tdcy.sys.util.BizNoUtils;
import com.tdcy.sys.util.ParamUtils;
import com.tdcy.sys.util.SeqUtils;
import com.tdcy.sys.util.wx.GenerateQrCodeUtil;
import com.tdcy.sys.util.wx.WxUtils;

/**
 * @Description 预付订单表Service实现类
 */
@Service
public class WxPaySvcImpl implements IWxPaySvc {

	@Resource
	IWxPayDAO wxpayDAO;

	@Resource
	IWxRefundDAO refundDAO;

	@Resource
	ISeqNoSvc seqSvc;

	/**
	 * 扫码支付的预支付订单生成
	 */
	@Override
	@Transactional
	public WxPayEO prepay(WxPayEO wxpay) {
		Map<String, String> resultMap = new UnifiedorderInf().execute(wxpay);

		String prepay_id = resultMap.get("prepay_id");
		String code_url = resultMap.get("code_url");
		wxpay.setPrepayId(prepay_id);
		wxpay.setCodeUrl(code_url);
		wxpay.setPreorderId(SeqUtils.getMaxNo("pre_order_id"));
		wxpayDAO.save(wxpay);

		return wxpay;
	}

	@Override
	public BufferedImage getQrCode(String payBizNo) {
		WxPayEO wxpay = wxpayDAO.queryByBizNo(payBizNo);
		String qrCodeUrl = wxpay.getCodeUrl();
		BufferedImage bi = GenerateQrCodeUtil.encodeQrcode(qrCodeUrl);
		return bi;
	}

	public void wxcallBack(WxPayEO eo) {
		wxpayDAO.updateByPayBizNo(eo.getPayBizno(), eo.getWxOrderNo(), eo.getPayStatus());
	}

	@Override
	public PageInfo<WxPayEO> queryPrePayList(WxPayCondition wpcondition) {
		return wxpayDAO.getPageInfo(wpcondition);
	}

	/**
	 * 查询订单状态
	 */
	@Override
	public String queryOrderStatus(String payBizNo) {
		WxPayEO teo = wxpayDAO.queryByBizNo(payBizNo);
		if (teo == null) {
			throw new QuickuException("预付订单(" + payBizNo + ")记录不存在");
		}
		Map<String, String> resultMap = new OrderQueryInf().execute(teo);

		String trade_state = resultMap.get("trade_state");

		return trade_state;
	}

	/***
	 * 退款
	 */
	@Override
	public Map<String, String> refund(WxPayEO eo) {
		Map<String, String> retMap = new HashMap<String, String>();
		String refendno = BizNoUtils.getWxRefundNo("T");
		try {
			Map<String, String> resultMap = new RefundInf().execute(eo);
			// 退款成功，从插入退款记录表
			WxRefundEO refundeo = new WxRefundEO();
			refundeo.setPayBizno(eo.getPayBizno());
			refundeo.setPayRefundNo(refendno);
			refundeo.setRefundFee(eo.getPayMoney());
			refundeo.setTotalFee(eo.getPayMoney());
			refundeo.setRefundStatus("SUCCESS");
			refundeo.setWxOrderNo(eo.getWxOrderNo());
			refundeo.setWxRefundId(seqSvc.getMaxNo("wx_refund_id"));
			refundeo.setWxRefundNo(resultMap.get("refund_id"));
			refundDAO.save(refundeo);

			// 更新对应支付记录的支付状态
			wxpayDAO.updateByPayBizNo(eo.getPayBizno(), eo.getWxOrderNo(), "REFUND SUCCESS");

		} catch (Exception ex) {
			// 退款失败,需要插入退款记录表
			WxRefundEO refundeo = new WxRefundEO();
			refundeo.setPayBizno(eo.getPayBizno());
			refundeo.setPayRefundNo(refendno);
			refundeo.setRefundFee(eo.getPayMoney());
			refundeo.setTotalFee(eo.getPayMoney());
			refundeo.setRefundStatus("FAIL");
			refundeo.setWxOrderNo(eo.getWxOrderNo());
			refundeo.setWxRefundId(seqSvc.getMaxNo("wx_refund_id"));
			refundDAO.save(refundeo);
		}

		return retMap;
	}

	@Override
	public Map<String, String> getWxPackage(Map<String, String> paramMap) {
		String apiKey = ParamUtils.getWxApiSecretkey();
		paramMap.put("appid", ParamUtils.getWxAppId()); // appid
		paramMap.put("mch_id", ParamUtils.getWxMchId()); // 商户号
		paramMap.put("nonce_str", WxUtils.getNonceStr()); // 随机数

		paramMap.put("sign", WxUtils.getSign(paramMap, apiKey));
		return paramMap;
	}
}
